------------------------------------------------------------------------------------------------------------------------------------------------
local function language_change_say(theNPC)
    theNPC.CHAT_TABLE = {}
    pcall(function()
        -- theNPC.npc_base_lib:Get_Language() == "ch"
        theNPC.CHAT_TABLE = TUNING.NPC_CHAT_TABLE[ theNPC.npc_base_lib:Get_Language() ] ["npc_event_telestaff"] or {}
    end)
end
------------------------------------------------------------------------------------------------------------------------------------------------
local function Time_Out_Leave(inst)
    local theNPC = inst.entity:GetParent()
    local time = theNPC.npc_base_lib:Get_Time_Out()
    if time then
        inst:DoTaskInTime(time,function()
            inst:Remove()
            theNPC:AddDebuff("npc_event_leave","npc_event_leave")
            -- theNPC.npc_base_lib:Say(theNPC.CHAT_TABLE.time_out)
            print("Warning : npc time out and leave")
        end)
    end
end
local function SpwanTheItem(theNPC,temp_locpos,playerPoint)
    local Points = theNPC.npc_base_lib:GetSurroundPoints({
        target = temp_locpos,
        range = 6,
        num = 12
    })


    for i, pt in pairs(Points) do
        local item_name = "log"
        if i == 1 then
            item_name = theNPC.npc_base_lib:GetRandom(theNPC.npc_base_lib:Get_Base_Food_List())
        elseif i == 2 then
            item_name = theNPC.npc_base_lib:GetRandom(theNPC.npc_base_lib:Get_Cooked_Food_List())
        elseif i == 3 then
            item_name = theNPC.npc_base_lib:GetRandom(theNPC.npc_base_lib:Get_Equipments_Hand())
        elseif i == 4 then
            item_name = theNPC.npc_base_lib:GetRandom(theNPC.npc_base_lib:Get_Equipments_Hats())
        elseif i == 5 then
            item_name = theNPC.npc_base_lib:GetRandom(theNPC.npc_base_lib:Get_Equipments_Body())
        elseif i == 6 then
            item_name = theNPC.npc_base_lib:GetRandom(theNPC.npc_base_lib:Get_Special_Materials())
        else
            item_name = theNPC.npc_base_lib:GetRandom(theNPC.npc_base_lib:Get_Base_Materials())            
        end
        SpawnPrefab(item_name).Transform:SetPosition(pt.x,0,pt.z)
    end
end

local function Use_Telestaff(theNPC,theplayer)
    local pt = theplayer.npc_base_lib:GetRandomPoint(theplayer,theplayer,false)


    local function step_3()
        SpawnPrefab("lightning").Transform:SetPosition(pt.x,0,pt.z)
        SpawnPrefab("lightning").Transform:SetPosition(pt.x+1,0,pt.z+1)
        theNPC.Transform:SetPosition(pt.x+1, 0, pt.z+1)
        theNPC.sg:GoToState("wakeup")
        theNPC:Show()
        if theplayer.sg then
            theplayer.sg:GoToState("wakeup")
            theplayer.SoundEmitter:PlaySound("dontstarve/common/staffteleport")
        end
        theNPC.teleport_end_flag = true

        if theplayer.components.sanity then
            theplayer.components.sanity:SetPercent(0)
        end
        SpwanTheItem(theNPC,pt,nil)
    end

    local function step_2()
        theplayer.__temp_telport_task = theplayer:DoPeriodicTask(0.1,function()
            if theNPC.npc_base_lib:Dsitance_T2P(theplayer,pt) > 1 then
                theplayer.Transform:SetPosition(pt.x, 0, pt.z)
            else
                if theplayer.__temp_telport_task then
                    theplayer.__temp_telport_task:Cancel()
                    theplayer.__temp_telport_task = nil
                end

                theplayer:SnapCamera()
                theplayer:ScreenFade(true, 1)
                theNPC:DoTaskInTime(1,step_3)
                
                
            end
        end)

    end


    local function step_1()
        if theplayer.components.locomotor ~= nil then
            theplayer.components.locomotor:StopMoving()
        end
        if theplayer.sg then
            theplayer.sg:GoToState("forcetele")
        end
        SpawnPrefab("lightning").Transform:SetPosition(theNPC.Transform:GetWorldPosition())
        SpawnPrefab("lightning").Transform:SetPosition(theplayer.Transform:GetWorldPosition())

        theNPC:DoTaskInTime(3,step_2)
        theNPC:Hide()

    end
    

    if theNPC.teleport_start_flag ~= true then
        theNPC.teleport_start_flag = true
        step_1()        
    end

    return theNPC.teleport_end_flag
end
-------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------




local function NPC_TASKS_INIT(inst)
    local theNPC = inst.entity:GetParent()
    language_change_say(theNPC)
    Time_Out_Leave(inst)
    
    -- theNPC.npc_base_lib:Equip_Random_Hat()
    -- theNPC.npc_base_lib:Equip_Random_Cloth()
    -- theNPC.npc_base_lib:Equip_Random_Weapon()
    local weapon = SpawnPrefab("telestaff")
    theNPC.npc_base_lib:Change_Item_Skin(weapon)
    theNPC.npc_base_lib:Equip(weapon)
    theNPC:AddTag("INLIMBO")
    theNPC:AddTag("notarget")
    theNPC:AddTag("noattack")
    theNPC:AddTag("invisible")
    -- theNPC:AddTag("Unable_To_Refuse")
    theNPC.npc_event = inst.prefab
end

local function NPC_TASKS(inst)
    local theNPC = inst.entity:GetParent()
    if TheWorld.state.isnight  or TheWorld:HasTag("cave") then
        theNPC.npc_base_lib:Try_2_Set_Light(true)
    else
        theNPC.npc_base_lib:Try_2_Set_Light(false)
    end
    local theplayer = theNPC.__link_player
    if theplayer == nil or theplayer:IsValid() == false then
        -- theNPC:RemoveDebuff(inst.prefab)
        inst:Remove()
        theNPC:AddDebuff("npc_event_leave","npc_event_leave")
        print("Warning : theNPC.__link_player == nil")
        return
    end

    if theNPC.event_step == nil then

        if theNPC.npc_base_lib:Close_2_Target_In_Range({range = 5}) == true then
            theNPC.event_step = 1
        end        
    elseif theNPC.event_step == 1 then
        theNPC.npc_base_lib:Say(theNPC.CHAT_TABLE.found_things)
        theNPC.event_step = theNPC.event_step + 1

    elseif theNPC.event_step == 2 then
        if theNPC.npc_everything_data:Add("task_time_wait_00",1)%3 == 0 then
            theNPC.event_step = theNPC.event_step + 1
        end
    elseif theNPC.event_step == 3 then
        theNPC.npc_base_lib:Action_Castspell()
        theNPC.SoundEmitter:PlaySound("dontstarve/common/staffteleport")
        theNPC.event_step = theNPC.event_step + 1

    elseif theNPC.event_step == 4 then
        if  theNPC.npc_everything_data:Add("task_time_wait_01",1)%2 == 0 then
            theNPC.event_step = theNPC.event_step + 1
        end

    elseif theNPC.event_step == 5 then        
        if Use_Telestaff(theNPC,theplayer) then
            theNPC.event_step = 6
        end       
    elseif theNPC.event_step == 6 then
       if theNPC.npc_everything_data:Add("task_time_wait_02",1)%14 == 0 then
            theNPC.event_step = theNPC.event_step + 1
        end        
    elseif theNPC.event_step == 7 then
        -- theNPC.event_step = theNPC.event_step + 1
        -- theNPC:RemoveDebuff(inst.prefab)
        inst:Remove()
        theNPC.npc_base_lib:Say("Bye ~ ")
        -- theNPC.npc_base_lib:Say(theNPC.CHAT_TABLE.hahaha)

        theNPC:AddDebuff("npc_event_leave","npc_event_leave")
    end
end
--------------------------------------------------------------------------------------------------------------------------------------------------

local function OnAttached(inst,target) -- when the debuff on or player is newSpawn(or through the cave)
    inst.entity:SetParent(target.entity)
    inst.Network:SetClassifiedTarget(target)
    local NPC = inst.entity:GetParent()
    local flag ,error_code= pcall(function(inst,target)
        if TheWorld.ismastersim then

            NPC_TASKS_INIT(inst)


        end
    end,inst,target)
    if flag == false  then
        print("Error : OnAttached(inst,target) ",inst.prefab)
        print(error_code)
        NPC:Remove()
    end
end

local function OnDetached(inst) -- When eliminating from the outside
    local player = inst.entity:GetParent()   
    -- print(" FROM OUSIDE REMOVE ")
    
    -- inst:Remove()
end

local function ExtendDebuff(inst)
    -- inst.countdown = 3 + (inst._level:value() < CONTROL_LEVEL and EXTEND_TICKS or math.floor(TUNING.STALKER_MINDCONTROL_DURATION / FRAMES + .5))
end



local function OnUpdate(inst,ismastersim)
    local NPC = inst.entity:GetParent()
    local flag,error_code = pcall(function(inst,ismastersim)
        -- local NPC = inst.entity:GetParent()

        NPC_TASKS(inst)


    end,inst,ismastersim)
    if flag == false then
        print("Error : OnUpdate(inst,ismastersim) ,step:",NPC.event_step ,inst.prefab)
        print(error_code)
        NPC:Remove()
    end
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddNetwork()

    inst:AddTag("CLASSIFIED")


    -- inst:DoPeriodicTask(1, OnUpdate, nil, TheWorld.ismastersim)  -- in one seconds
    inst:DoPeriodicTask( 0.5, OnUpdate, nil, TheWorld.ismastersim)  -- in 0.5 seconds

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("debuff")
    inst.components.debuff:SetAttachedFn(OnAttached)
    inst.components.debuff.keepondespawn = false -- 是否保持debuff 到下次登陆
    -- inst.components.debuff:SetDetachedFn(inst.Remove)
    inst.components.debuff:SetDetachedFn(OnDetached)
    -- inst.components.debuff:SetExtendedFn(ExtendDebuff)
    -- ExtendDebuff(inst)


    return inst
end

return Prefab("npc_event_telestaff", fn)
